#ifndef CONST_H
#define CONST_H

#pragma region Descriptors

#define GDT_SIZE 256
#define IDT_SIZE 256

#define GDT_CODE_SELECTOR (1 * 8)
#define GDT_DATA_SELECTOR (2 * 8)
#define GDT_SYSCALL_SELECTOR (3 * 8)

#define SEG_TYPE_CODE 1 << 3
#define SEG_TYPE_DATA 0 << 3
#define SEG_TYPE_SYSCALL (0xC << 8)
#define SEG_TYPE_READ_WRITE 1 << 1

// 放置普通数据和代码的
#define SEG_S_NORMAL 1 << 4
// 非数据和代码，比如TSS，LDT，各种门
#define SEG_S_SYSTEM 0 << 4

#define SEG_DPL_0 0 << 5
#define SEG_DPL_3 3 << 5

#define SEG_RPL_0 (0 << 0)
#define SEG_RPL_3 (3 << 0)

#define SEG_P 1 << 7

#define SEG_D_32 1 << 14
#define SEG_D_64 0 << 14

#define SEG_G_4KB 1 << 15
#define SEG_G_1B 0 << 15

#define SEG_TYPE_TSS 0x9

#define GATE_P 1 << 15
#define GATE_DPL_0 0 << 13
#define GATE_DPL_3 3 << 13
#define GATE_D_32 1 << 11
#define GATE_TYPE_INTERRUPT 0x6 << 8

// enable interrupts
#define EFLAGS_IF (1 << 9)
#define EFLAGS_DEFAULT (1 << 1)

#pragma endregion

#pragma region Interrupt Request

#define IRQ0_DE 0
#define IRQ1_DB 1
#define IRQ2_NMI 2
#define IRQ3_BP 3
#define IRQ4_OF 4
#define IRQ5_BR 5
#define IRQ6_UD 6
#define IRQ7_NM 7
#define IRQ8_DF 8
#define IRQ10_TS 10
#define IRQ11_NP 11
#define IRQ12_SS 12
#define IRQ13_GP 13
#define IRQ14_PF 14
#define IRQ16_MF 16
#define IRQ17_AC 17
#define IRQ18_MC 18
#define IRQ19_XM 19
#define IRQ20_VE 20

#define ERR_PAGE_P (1 << 0)
#define ERR_PAGE_WR (1 << 1)
#define ERR_PAGE_US (1 << 1)

#define ERR_EXT (1 << 0)
#define ERR_IDT (1 << 1)

#pragma endregion

#pragma region Programmable Interrupt

// fixed port address in 8259A PIC
#define PIC0_ICW1 0x20
#define PIC0_ICW2 0x21
#define PIC0_ICW3 0x21
#define PIC0_ICW4 0x21
#define PIC0_OCW2 0x20
// interrupt mask register
// 1 bit means interrupt is disable
#define PIC0_IMR 0x21

#define PIC1_ICW1 0xa0
#define PIC1_ICW2 0xa1
#define PIC1_ICW3 0xa1
#define PIC1_ICW4 0xa1
#define PIC1_OCW2 0xa0
#define PIC1_IMR 0xa1

#define PIC_ICW1_ICW4 (1 << 0)
#define PIC_CASCADED (0 << 1)
#define PIC_CASCADED_PORT_NUM 2
#define PIC_CASCADED_PORT (1 << PIC_CASCADED_PORT_NUM)
#define PIC_ICW1_ALWAYS_1 (1 << 4)
#define PIC_ICW4_8086 (1 << 0)
#define PIC_OCW2_EOI (1 << 5)

// custom value must be greater than 0x1F
#define IRQ_PIC_START 0x20

#pragma endregion

#pragma region Programmable Interrupt Timer

#define IRQ_TIMER 0x20

// Standard PIT input frequency
#define PIT_TIMER_FREQ 1193182
#define PIT_CHANNEL0_DATA_PORT 0x40
#define PIT_COMMAND_MODE_PORT 0x43
#define TICK_COUNT_PER_SECOND 100
#define TICK_MS (1000 / TICK_COUNT_PER_SECOND)

#define PIT_CHANNLE0 (0 << 6)
#define PIT_LOAD_LOHI (3 << 4)
#define PIT_MODE3 (3 << 1)

#pragma endregion

#pragma region Virtual Memory

// Extended BIOS Data Area
#define MEMORY_EBDA_START 0x80000
#define PAGE_SIZE 4096
#define KERNEL_END_ADDRESS (1024 * 1024) // 1MB
#define KERNEL_TASK_END (128 * 1024 * 1024)
#define PDE_COUNT 1024
#define PTE_COUNT 1024

#define PTE_P (1 << 0)
#define PTE_W (1 << 1)
#define PTE_U (1 << 2)

#define PDE_P (1 << 0)
#define PDE_U (1 << 2)

#define TASK_ADDRESS_BASE (0x80000000)
#define KERNEL_STACK_SIZE (8 * 1024) // 内核栈

#pragma endregion

#pragma region Debug

#define COM1_PORT 0x3F8

#pragma endregion

#pragma region Task

#define TASK_NAME_SIZE 32
#define TASK_TICKS 20
// Small size results in stack overflow
#define IDLE_TASK_STACK_SIZE 1024
#define TASK_FLAG_SYSTEM (1 << 0)
#define TASK_MAX_NUM 128

#define ET_EXEC         2   // 可执行文件
#define ET_386          3   // 80386处理器

#define PT_LOAD         1   // 可加载类型
#define MEM_TASK_STACK_TOP          (0xE0000000)        // 初始栈的位置  
#define MEM_TASK_STACK_SIZE         (PAGE_SIZE * 500)   // 初始500KB栈
#define MEM_TASK_ARG_SIZE           (PAGE_SIZE * 4)


#pragma endregion

#pragma region System Call

#define SYS_SLEEP 0
#define SYS_GET_PID 1
#define SYS_FORK 2
#define SYS_EXECVE 3
#define SYS_YIELD 4

#define SYS_PRINT_MSG 99

#define SYSCALL_PARAM_COUNT 5

#pragma endregion

#endif